from fastdtw import fastdtw
import json
import math
from dtaidistance import dtw
import mysql.connector
from datetime import datetime, timedelta
import Test_Draw_Map

# MySQL数据库配置
config = {
    'user': 'root',
    'password': '123456',
    'host': '192.168.124.8',
    'database': 'vanna_ai',
    'port': '3333',
}


def find_similar_segments(traj1, traj2, window_size, threshold, step=1):
    similar_segments = []
    distances1 = [combined_distance(traj1[i], traj1[i + 1]) for i in range(len(traj1) - 1)]
    distances2 = [combined_distance(traj2[i], traj2[i + 1]) for i in range(len(traj2) - 1)]
    max_similarity = -1
    best_segment = None
    print(f"Total segments to process: {len(distances1) - window_size + 1}")

    for i in range(0, len(distances1) - window_size + 1, step):
        sub_distances1 = distances1[i:i + window_size]
        for j in range(0, len(distances2) - window_size + 1, step):
            sub_distances2 = distances2[j:j + window_size]
            try:
                distance = dtw.distance(sub_distances1, sub_distances2)
                if distance < threshold:
                    similarity = 1 / (1 + distance)
                    if similarity > max_similarity:
                        max_similarity = similarity
                        best_segment = (i, i + window_size, j, j + window_size, similarity)
                    similar_segments.append((i, i + window_size, j, j + window_size, similarity))
            except Exception as e:
                print(f"Error calculating distance for segment {i} and {j}: {e}")
    return similar_segments, max_similarity, best_segment


def haversine(point1, point2):
    """计算两点之间的球面距离（单位：公里）"""
    lat1, lon1 = map(math.radians, point1[:2])
    lat2, lon2 = map(math.radians, point2[:2])
    dlat = lat2 - lat1
    dlon = lon2 - lon1
    a = math.sin(dlat / 2) ** 2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon / 2) ** 2
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
    return 6371 * c  # 地球半径约6371公里


def euclidean_time(point1, point2):
    """计算两个时间戳之间的欧氏距离（单位：秒）"""
    return abs(point1[2] - point2[2])


def combined_distance(point1, point2):
    """计算空间和时间的组合距离"""
    space_distance = haversine(point1, point2)
    time_distance = euclidean_time(point1, point2)
    return math.sqrt(space_distance ** 2 + (time_distance / 3600) ** 2)  # 将时间距离转换为小时


def extract_coordinates_with_time(trajectory):
    """从轨迹中提取坐标和时间戳"""
    if not trajectory or not all(isinstance(point, tuple) and len(point) >= 3 for point in trajectory):
        raise ValueError("轨迹数据无效：每个点应为至少包含三个数值的元组（经度、纬度、时间戳）")
    return [(point[0], point[1], point[2]) for point in trajectory]


def calculate_dtw_distance(coords1, coords2):
    """计算两个坐标序列的DTW距离"""
    # 使用 fastdtw 近似计算 DTW 距离，使用组合距离函数
    distance, _ = fastdtw(coords1, coords2, dist=combined_distance)
    return distance


# 解析两个飞行数据，并计算它们之间的协同行为
def load_flight_data(file_path):
    # 加载飞行数据，假设数据已按时间戳排序
    data = []
    with open(file_path, 'r', encoding='utf-8') as file:
        # 解析文件内容并存储到data列表中，每个元素是一个字典，包含时间戳、经度、纬度、高度、速度、航向等信息
        file_data = json.loads(file.read())
        traces = file_data['trace']
        timestamp = file_data['timestamp']
        reg_id = file_data['r']
        for trace in traces:
            data.append([
                trace[1],  # 经度
                trace[2],  # 纬度
                timestamp  # 时间戳
            ])
    return data, reg_id


def extract_date(timestamp):
    # 将时间戳转换为 datetime 对象
    dt_object = datetime.fromtimestamp(timestamp)

    # 将 datetime 对象格式化为 YYYY-MM-DD 格式的字符串
    date_string = dt_object.strftime('%Y-%m-%d')

    # 打印格式化后的日期字符串
    print(f"格式化后的日期字符串: {date_string}")
    return date_string

def insert_mysql(reg_id1, reg_id2, start_time1, end_time1, start_time2, end_time2, similarity_percentage, average_similarity):
    connection = mysql.connector.connect(**config)
    cursor = connection.cursor()
    time = extract_date(start_time1)
    cursor.execute(
        "INSERT INTO collaborative_event_table (reg_id1, reg_id2, time, start_time1,end_time1, start_time2,end_time2,average_similarity_percentage,best_segment_similarity_percentage)"
        " VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)",
        (reg_id1, reg_id2, str(time), str(start_time1), str(end_time1), str(start_time2), str(end_time2),
         str(average_similarity), str(similarity_percentage))
    )
    connection.commit()


def select_aircraft_trace(cursor, reg_id):
    """
    查询数据库中特定飞机的轨迹信息。

    参数:
    icao (str): 飞机的ICAO代码。
    reg_id (str): 飞机的注册ID。
    cursor (mysql.connector.cursor.MySQLCursor): 数据库游标。

    返回:
    tuple: 包含飞机轨迹信息的元组，每个元素是一个包含轨迹信息的字典。
    """
    query = "SELECT timestamp , latitude, longitude FROM military_aircraft_trace WHERE reg_id = %s limit 3000"
    cursor.execute(query, (reg_id,))
    rows = cursor.fetchall()
    # classified_data = classify_by_day(rows)
    return rows
    # return classified_data


def classify_by_day(rows):
    classified_data = {}
    for row in rows:
        current_time = row[0]
        dt_object = datetime.fromtimestamp(current_time)
        date_key = dt_object.date()  # 使用日期作为键
        if date_key not in classified_data:
            classified_data[date_key] = []
        classified_data[date_key].append(row)
    return classified_data


def select_all_aircraft(cursor):
    """
    :param cursor:
    :return: 飞机实体
    """
    query = "SELECT icao, reg_id FROM military_aircraft"
    cursor.execute(query)
    aircraft_data = cursor.fetchall()
    return aircraft_data


def select_aircraft_trace_by_date(cursor, reg_id, date_str):
    # 将日期字符串转换为 datetime 对象
    date_object = datetime.strptime(date_str.strftime('%Y-%m-%d'), '%Y-%m-%d')

    # 计算当天的开始时间戳（00:00:00）
    start_time = int(date_object.timestamp())

    # 计算当天的结束时间戳（23:59:59）
    end_time = int((date_object + timedelta(days=1) - timedelta(seconds=1)).timestamp())

    # 查询该日期范围内的轨迹信息
    query = "SELECT currenttime, latitude, longitude FROM military_aircraft_trace WHERE reg_id = %s AND currenttime BETWEEN %s AND %s"
    cursor.execute(query, (reg_id, start_time, end_time))
    rows = cursor.fetchall()

    # 按天分类（虽然这里已经是按天查询，但可以保留分类功能）
    return rows



def main():
    # 读取所有飞机实体
    connection = mysql.connector.connect(**config)
    cursor = connection.cursor()
    aircraft_data = select_all_aircraft(cursor)
    for aircraft in aircraft_data:
        # 查询出该飞机的轨迹信息
        trajectory1 = select_aircraft_trace(cursor, aircraft[1])
        if not trajectory1:
            continue
        reg_data1 = aircraft[1]
        for other_aircraft in aircraft_data:
            reg_data2 = other_aircraft[1]
            if reg_data2 != reg_data1:        # 使用根据时间处理好的数据进行DTW计算 现在已经有了其中一个数据，还需要另外一个飞机的数据
                trajectory2 = select_aircraft_trace(cursor, reg_data2)
                if not trajectory2:
                    print("该飞机没有轨迹信息")
                    continue

                similar_segments, max_similarity, best_segment = find_similar_segments(trajectory1, trajectory2,
                                                                                       200, 5, step=50)
                average_similarity_percentage = 0.0
                # 计算整体平均相似度
                if similar_segments:
                    average_similarity = sum(segment[4] for segment in similar_segments) / len(similar_segments)
                    average_similarity_percentage = average_similarity * 100
                # 输出相似度最高的两架飞机的对应轨迹下标及其相似度百分比
                # 计算整体平均相似度
                if similar_segments:
                    average_similarity = sum(segment[4] for segment in similar_segments) / len(similar_segments)
                    average_similarity_percentage = average_similarity * 100
                # 输出相似度最高的两架飞机的对应轨迹下标及其相似度百分比
                for segment in similar_segments:
                    if segment[4] > average_similarity + 0.5:
                        insert_mysql(reg_data1, reg_data2, trajectory1[segment[0]][2], trajectory1[segment[1]][2],
                                     trajectory2[segment[2]][2], trajectory2[segment[3]][2], segment[4],
                                     average_similarity_percentage)
                        print(f"两架飞机的轨迹相似度百分比：{segment[4] * 100:.2f}%")



if __name__ == '__main__':
    main()

